#include <iostream>
#include <windows.h>
#include <string>
 
using namespace std;
int derangement(int a) // 全错位排列计算
{
    if (a==1) return 0;
    if (a==2) return 1;
    return (a-1) * (derangement(a-1) + derangement(a-2)); // 递归公式: D(n) = (n-1)*(D(n-1) + D(n-2))) 
}

int factorial(int fctl) // 定义阶乘
{
	int f;
	if(fctl==0 || fctl==1)
	{
	    f=1;
    }
	else
    {
		f=factorial(fctl-1)*fctl;
    }
	return f;
}

int main() // 用户界面部分
{
    system("title [Greeting-Cards Plus+ ] version 2.7");
    MessageBox(NULL,"         Greeting-Cards Plus 说明   \n\n输入的数字应为整数\n  [总数]意为 参与此事件的总样本数（不一定全错位）。\n  [错位数]意为 已错位的样本的数量。\n  [已知的错位数]意为 已知错位的（至少错位的）样本的数量。\n>>功能更加强大!"," Greeting-Cards Plus",MB_OK);
    system("color 1f");
	cout << " Greeting-Cards Plus+\n";
    cout << "【  非全错位排列求解程序】\n";
	for(int rd; rd<=999; rd++)
    {
        system("color 1f");
        int n,a,v;
        cout << "\n=-----------==================================================\n";
        cout << " 请输入总数'n': "; cin >> n;
        cout << " 请输入已知的错位数'a'(a<=n): "; cin >> a;
        cout << ">>processing...\n\n";
        cout << "   记: 总错位数为Der\n";
        if (n<=0)
        {
            Sleep(400);
            cout << ">>递推失败...\n";
            MessageBox(NULL,"*An Unexpected Error has occurred!\n>>Not available index of 'n' inputted!\n>>wrong number: 0x00011\n","Process Error!",MB_OK); 
            cout << ">>*Not available index of '"<<n<<"' inputted!\n";Sleep(500);
            cout << ">>'n'should be at least larger than 0"<<endl;
            system("pause");
        }
        else if (a<=0)
        {
            Sleep(400);
            cout << ">>递推失败...\n";
            MessageBox(NULL,"*An Unexpected Error has occurred!\n>>Not available index of 'a' inputted!\n>>wrong number: 0x00012\n","Process Error!",MB_OK); 
            cout << ">>*Not available index of '"<<a<<"' inputted!\n";Sleep(500);
            cout << ">>'a'should be at least larger than 0\n"<<endl;
            system("pause");
        }
        else if (n==1)
        {
            if(a==1)
            {
                cout << ">>无法使用递推，但已知结果为 "<<derangement(n)<<"\n";
            }
            else
            {
                cout << "*Input interrupted!\n"<<endl;
            }
        }
        else if (n==2)
        {
            if(a==1)
            {
                cout << ">>无法使用递推，但已知结果为 "<<derangement(n)+derangement(n-1)<<"\n";
            }
            else
            {
                cout << "*Input interrupted!\n"<<endl;
            }
        }
        else if (n>70)	
        {	
            system("cls");	
            system("color 0a");	
            cout <<">>您输入的数值‘"<<n<<"’大于程序安全值70。"<<endl;	
            if(MessageBox(NULL,"本程序涉及阶乘等较为庞大的计算，您输入的数值大于70，为避免系统运算量过大导致数值溢出，已启动保护措施。请点击‘取消’以中止本次危险的运算。\n\n!!!您确定要强制执行吗?\n 如果确认强制执行计算程序，请点击‘确认’以执行。\n\n>>经用户确认后如有因强制执行过大的数值运算而造成系统崩溃或硬件损坏等情况，本程序及其制作者均有权不承担后果。<<","程序强制执行警告!",MB_YESNO | MB_ICONEXCLAMATION)==IDYES)	
            {	
                cout<<"祝您好运。"<<endl;	
                Sleep(1000);	
                while(1)	
                {	
                	if(MessageBox(NULL,"关键性错误",":(",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)	
                	{	
                		break;	
					}	
                    else	
                    {	
                        WinExec("sim-BSOD.exe",SW_MAXIMIZE);	
                    }	
				}	
            }	
            else	
            {	
                cout<<"请注意输入的数值大小（输入的数值须小于等于70）"<<endl;	
                Sleep(250);	
            }	
        }
        else if (v>50)
        {	
            system("cls");	
            system("color 0a");	
            cout <<">>您输入的数值之差‘"<<v<<"’大于程序安全值50。"<<endl;	
            if(MessageBox(NULL,"本程序涉及阶乘等较为庞大的计算，您输入的数值差大于50，为避免系统运算量过大导致数值溢出，已启动保护措施。请点击‘取消’以中止本次危险的运算。\n\n!!!您确定要强制执行吗?\n 如果确认强制执行计算程序，请点击‘确认’以执行。\n\n>>经用户确认后如有因强制执行过大的数值运算而造成系统崩溃或硬件损坏等情况，本程序及其制作者均有权不承担后果。<<","程序强制执行警告!",MB_YESNO | MB_ICONEXCLAMATION)==IDYES)	
            {	
                cout<<"祝您好运。"<<endl;	
                Sleep(1000);	
                while(1)	
                {	
                	if(MessageBox(NULL,"关键性错误",":(",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)	
                	{	
                		break;	
					}	
                    else	
                    {	
                        WinExec("sim-BSOD.exe",SW_MAXIMIZE);	
                    }	
				}	
            }	
            else	
            {	
                cout<<"请注意输入的数值大小（输入的数值差须小于等于50）"<<endl;	
                Sleep(250);	
            }	
        }
        else
        {
            int fls,Comb,res,cnt,g; // Comb是组合数Combination的缩写
    		v=n-a;
    		fls=a;
    		res=0; 
			while (a<=n)
            {
                cnt=a-fls;
                Comb=factorial(cnt)*factorial(v-cnt);
                res=res+derangement(a)*factorial(v)/Comb; // a,fls为定值;v,cnt为变量。
                a=a+1;
                g=a;
				cout << " \n>>Der("<<a<<") = "<<res<< endl; // 输出 D(n)
            }
            cout<<" 最后一次结果为所要答案。"<<endl;
        }
        if(rd%10==5)
        {
            system("color 0a");
            system("title 清除历史记录");
            cout <<" \n>>data need to be cleaned.\n";
            system("pause");
            system("cls");
            system("title [Greeting-Cards Plus+ ] version 2.7");
            cout<<" \n>>data cleaned completed\n"<<endl;
        }
    }
    system("pause");
    return 0;
}